﻿using System;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Services;
using Casamiel.API.Infrastructure.Exceptions;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain.Request.IC;
using MediatR;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    ///  
    /// </summary>
    public sealed class CancelOrderCommandHandler : IRequestHandler<CancelOrderCommand, Zmodel>
    {
        private readonly NLog.ILogger logger = LogManager.GetLogger("MeiTuanOrderService");
        private readonly IIcApiService _icApiService;
        private readonly IOrderService _order;
        private readonly ICasaMielSession _session;
        private readonly IStoreApiService _storeApiService;
        private readonly IRefundService _refundService;
        private readonly IMemberCashCouponService _memberCashCouponService;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="memberCashCouponService"></param>
        /// <param name="order"></param>
        /// <param name="iicApiService"></param>
        /// <param name="storeApiService"></param>
        /// <param name="session"></param>
        /// <param name="refundService"></param>
        public CancelOrderCommandHandler(IMemberCashCouponService memberCashCouponService, IOrderService order, IIcApiService iicApiService, ICasaMielSession session, IStoreApiService storeApiService, IRefundService refundService)
        {
            _memberCashCouponService = memberCashCouponService;
            _icApiService = iicApiService;
            _session = session;
            _storeApiService = storeApiService;
            _order = order;
            _refundService = refundService;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Zmodel> Handle(CancelOrderCommand request, CancellationToken cancellationToken)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }
            logger.Trace($"OrderCancel:{JsonConvert.SerializeObject(request)}");
            var orderInfo = await _order.GetByOrderCodeAsync<ICasaMielSession>(request.OrderCode).ConfigureAwait(false);
            if (orderInfo == null) {
                logger.Trace($"OrderCancel:订单不存在");
                return new Zmodel { code = 0, msg = "订单不存在" };
            }

            Zmodel d;

            //来源 0  蛋糕商城 1 美团 2 饿了么 3 京东 4 滴滴 5天猫 6 口碑 7 全国送商城 8 外卖
            switch (request.Source) {
                case 0:
                case 5:
                case 7:
                case 8:
                    bool back = false;
                    int orderstatus = 9;

                    using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                        var s = await _order.UpdateOrderStatusAndResBillNOAsync(orderInfo, orderstatus, orderInfo.ResBillNo, uow).ConfigureAwait(true);
                        back = s;
                        if (orderInfo.OrderType == 1) {
                            var take = await _order.UpdateOrderTakeStatus(orderInfo.OrderBaseId, -1, "", uow).ConfigureAwait(true);
                        }
                        var dis = await _order.UpdateOrderDiscountStatus(orderInfo.OrderBaseId, 1, uow).ConfigureAwait(true);
                        if (s) {
                            back = s;
                            uow.Commit();
                        } else {
                            uow.Rollback();
                        }
                    }

                    if (back) {
                        var req = new ThirdOrderBackReq { Tradeno = orderInfo.IcTradeNO };
                        d = await _icApiService.ThirdOrderBack(req).ConfigureAwait(false);
                        if (d.code == 0 || d.code == 205) {
                            JObject obj = JsonConvert.DeserializeObject<JObject>(d.content);
                            logger.Trace($"OrderCode:{orderInfo.OrderCode},tradeno_origin:{obj["tradeno_origin"].ToString()},tradeno:{obj["tradeno"].ToString()},");
                            var billno = obj["tradeno"].ToString();
                            orderInfo.ResBillNo = billno;
                            orderInfo.OrderStatus = (int)OrderStatus.Closed;

                            using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                await _order.OrderBaseUPdateAsync(orderInfo, uow).ConfigureAwait(false);
                            }

                            try {
                                var discountlist = await _order.GetListByOrderBaseId<ICasaMielSession>(orderInfo.OrderBaseId).ConfigureAwait(false);
                                if (discountlist.Any()) {
                                    int count = discountlist.Count;
                                    for (int i = 0; i < count; i++) {
                                        if (discountlist[i].DiscountCouponType == 2) {
                                            var cashentity = await _memberCashCouponService.FindAsync<ICasaMielSession>(discountlist[i].DiscountCouponId.ToString(CultureInfo.CurrentCulture)).ConfigureAwait(false);
                                            if (cashentity != null) {
                                                cashentity.State = 3;
                                                await _memberCashCouponService.UpdateAsync<ICasaMielSession>(cashentity).ConfigureAwait(false);
                                            }
                                        }
                                    }
                                }
                            } catch (System.Net.Http.HttpRequestException ex) {
                                logger.Error(ex.StackTrace);
                                throw new CasamielDomainException("", ex);
                            }
                        } else {
                            orderInfo = await _order.GetByOrderCodeAsync<ICasaMielSession>(request.OrderCode).ConfigureAwait(false);
                            //orderInfo.OrderStatus = orderstatus;
                            using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                var s = await _order.OrderBaseUPdateAsync(orderInfo, uow).ConfigureAwait(true);
                                back = s;
                                if (orderInfo.OrderType == 1) {
                                    var take = await _order.UpdateOrderTakeStatus(orderInfo.OrderBaseId, -1, "", uow).ConfigureAwait(true);
                                }
                                var dis = await _order.UpdateOrderDiscountStatus(orderInfo.OrderBaseId, 0, uow).ConfigureAwait(true);

                                if (s) {
                                    back = s;
                                    uow.Commit();
                                } else {
                                    uow.Rollback();
                                }
                            }
                        }
                    } else {
                        d = new Zmodel { code = 999, msg = "取消订单失败" };
                    }
                    break;
                case 1:
                case 2:
                case 3:
                    if (orderInfo.OrderStatus == (int)OrderStatus.Completed)//已经完成不能退货
                    {
                        return new Zmodel { code = 0, msg = "" };
                    }
                    var cback = new ThirdOrderBackReq { Tradeno = orderInfo.IcTradeNO };
                    d = await _icApiService.ThirdOrderBack(cback).ConfigureAwait(false);
                    logger.Trace($"thirdorderback,result:{JsonConvert.SerializeObject(d)},req:{JsonConvert.SerializeObject(cback)}");

                    if (d.code == 0 || d.code == 205) {
                        JObject obj = JsonConvert.DeserializeObject<JObject>(d.content);
                        logger.Trace($"OrderCode:{orderInfo.OrderCode},tradeno_origin:{obj["tradeno_origin"].ToString()},tradeno:{obj["tradeno"].ToString()},");
                        orderInfo.ResBillNo = obj["tradeno"].ToString();
                        using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                            orderInfo.OrderStatus = (int)OrderStatus.Cancelled;
                            await _order.OrderBaseUPdateAsync(orderInfo, uow).ConfigureAwait(false);
                        }
                    }
                    break;
                default:
                    d = new Zmodel { code = 999, msg = "取消订单失败" };
                    break;
            }


            //if (request.Source > 0)
            //{
            //    if (orderInfo.OrderStatus == 7)//已经完成不能退货
            //    {
            //        return new Zmodel { code = 0, msg = "" };
            //    }
            //    var cback = new ThirdOrderBackReq { tradeno = orderInfo.IcTradeNO };
            //    d = await _icApiService.thirdorderback(cback);
            //    logger.Trace($"thirdorderback,result:{JsonConvert.SerializeObject(d)},req:{JsonConvert.SerializeObject(cback)}");
            //}
            //else
            //{
            //    if (orderInfo.OrderStatus > 1)
            //    {
            //        return new Zmodel { code = 0, msg = "订单状态已经变化" };
            //    }
            //    var req = new IcConsumeBackReq { cardno = request.CardNO, phoneno = orderInfo.Mobile, tradeno = orderInfo.IcTradeNO };
            //    d = await _icApiService.icconsumeback(req);
            //    var refuandresult = await _refundService.OrderRefund(new OrderRefundReq { OrderCode = orderInfo.OrderCode, CancelReason = "超时退款" });
            //    logger.Trace($"UnPayOrderback,result:{JsonConvert.SerializeObject(d)},req:{JsonConvert.SerializeObject(req)}，{JsonConvert.SerializeObject(refuandresult)}");
            //}

            //if (d.code == 0 || d.code == 205)
            //{
            //    JObject obj = JsonConvert.DeserializeObject<JObject>(d.content);
            //    logger.Trace($"OrderCode:{orderInfo.OrderCode},tradeno_origin:{obj["tradeno_origin"].ToString()},tradeno:{obj["tradeno"].ToString()},");
            //    var billno = obj["tradeno"].ToString();
            //    orderInfo.ResBillNo = billno;
            //    orderInfo.OrderStatus = 8;
            //    orderInfo.CloseTime = DateTime.Now;
            //    using (var uow = _session.UnitOfWork(IsolationLevel.Serializable))
            //    {
            //        if (request.Source > 0)
            //        {

            //            var s = await _order.OrderBaseUPdateAsync(orderInfo, uow);
            //        }
            //        else
            //        {
            //            orderInfo.OrderStatus = 9;
            //            var s = await _order.OrderBaseUPdateAsync(orderInfo, uow);
            //            if (orderInfo.OrderType == 1)
            //            {
            //                var take = await _order.UpdateOrderTakeStatus(orderInfo.OrderBaseId, -1, "", uow);
            //            }
            //            var dis = await _order.UpdateOrderDiscountStatus(orderInfo.OrderBaseId, 1, uow);
            //        }
            //    }

            //    try
            //    {
            //        var discountlist = await _order.GetListByOrderBaseId<ICasaMielSession>(orderInfo.OrderBaseId);
            //        if (discountlist.Any())
            //        {
            //            int count = discountlist.Count;
            //            for (int i = 0; i < count; i++)
            //            {
            //                if (discountlist[i].DiscountCouponType == 2)
            //                {
            //                    var cashentity = await _memberCashCouponService.FindAsync<ICasaMielSession>(discountlist[i].DiscountCouponId.ToString());
            //                    if (cashentity != null)
            //                    {
            //                        cashentity.State = 3;
            //                        await _memberCashCouponService.UpdateAsync<ICasaMielSession>(cashentity);
            //                    }
            //                }
            //            }
            //        }
            //    }
            //    catch (Exception ex)
            //    {

            //        logger.Error(ex.StackTrace);
            //    }
            //}
            //else
            //{
            //    return d;
            //}
            if (request.IsRefund) {
                return d;
            }
            switch (request.Source) {
                case 1://美团
                    if (d.code == 0 || d.code == 205) {

                        var result = await _storeApiService.MeituanCancelV2Async(request.OrderCode.ToInt64(0), request.ReasonCode, request.Reason).ConfigureAwait(false);
                        logger.Trace($"MeituanCancelV2Async:{JsonConvert.SerializeObject(result)}");
                        //var dynamicdata = JsonConvert.DeserializeObject<JObject>(result);
                        //if (dynamicdata["ResultNo"].ToString() == "00000000")
                        //{
                        //    return new Zmodel { code = 0, msg = "" };
                        //}
                        return new Zmodel { code = result.Code, msg = result.Msg };
                    }
                    return d;

                default:
                    return d;

            }
        }
    }
}
